﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace repliback4.Net.Protocol.SASLMechanisms {

    /// <summary>
    /// http://www.faqs.org/rfcs/rfc4616.html
    /// </summary>
    public class Plain {
        protected static Regex msgRegex = new Regex( "^(?<authcid>[^\x00]+)?\x00(?<authzid>[^\x00]+)\x00(?<passwd>[^\x00]+)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture );
        const String NAME = "PLAIN";
        //[authzid] UTF8NUL authcid UTF8NUL passwd
        protected String authcid;
        protected String authzid;
        protected String passwd;
        public String MessageB64 {
            get { return Encode( this.Message ); }
            set { this.Message = Decode( value ); }
        }

        public static string Decode ( string value ) {
            byte[] b = Convert.FromBase64String( value );
            return Encoding.UTF8.GetString( b );
        }

        public static string Encode ( string value ) {
            byte[] b = Encoding.UTF8.GetBytes( value );
            return Convert.ToBase64String( b, Base64FormattingOptions.None );
        }
        public String Message {
            get { return this.MakeMessage( ); }
            set { this.ParseMessage( value ); }
        }

        public String AuthorizationIdentity {
            get { return this.authzid; }
            set { this.authzid = value; }
        }
        public String AuthenticationIdentity {
            get { return this.authcid; }
            set { this.authcid = value; }
        }
        public String Password {
            get { return this.passwd; }
            set { this.passwd = value; }
        }


        protected void ParseMessage ( string value ) {
            Match m = msgRegex.Match( value );
            this.AuthenticationIdentity = m.Groups["authcid"].Value;
            this.AuthorizationIdentity = m.Groups["authzid"].Value;
            this.Password = m.Groups["passwd"].Value;
        }

        protected string MakeMessage ( ) {
            return String.Format( "{0}\0{1}\0{2}", this.authcid, this.authzid, this.passwd );
        }

    }
}
